
#ifndef __TEXIMAGE_FONT__HEADER_FILE__
#define __TEXIMAGE_FONT__HEADER_FILE__

#include "coid/comm/binstream/filestream.h"
#include "coid/comm/binstream/cachestream.h"
#include "coid/comm/binstream/txtstream.h"
#include "coid/comm/dir.h"

#include "teximage.h"


////////////////////////////////////////////////////////////////////////////////
struct Font
{
    struct Char
    {
        SDL_Rect _rect;

        int16 _xoffs;
        int16 _yoffs;
        int16 _xadv;
        uint16 _page;

        char read( token& tin )
        {
            tin.skip_notchar('=');
            if( tin.is_empty() )
                return 0;

            char k = tin.touint_and_shift(1);

            tin.skip_notchar('=');
            _rect.x = tin.touint_and_shift(1);
            tin.skip_notchar('=');
            _rect.y = tin.touint_and_shift(1);
            tin.skip_notchar('=');
            _rect.w = tin.touint_and_shift(1);
            tin.skip_notchar('=');
            _rect.h = tin.touint_and_shift(1);
            
            tin.skip_notchar('=');
            _xoffs = tin.touint_and_shift(1);
            tin.skip_notchar('=');
            _yoffs = tin.touint_and_shift(1);
            tin.skip_notchar('=');
            _xadv = tin.touint_and_shift(1);
            tin.skip_notchar('=');
            _page = tin.touint_and_shift(1);
            return k;
        }
    };


    int print( TexImage& dst, int x, int y, const token& str, bool inv=false ) const
    {
        for( uint i=0; i<str.len(); ++i )
        {
            uchar k = str[i];

            if( k >= _chars.size() )
                continue;
            if( !_chars[k].is_set() )
                continue;

            const Char& ch = *_chars[k];
            SDL_Rect rdst;
            rdst.x = x + ch._xoffs + dst._rect.x;
            rdst.y = y + ch._yoffs + dst._rect.y;
            SDL_BlitSurface( inv ? _images_inv[ch._page]._surf : _images[ch._page]._surf,
                (SDL_Rect*)&ch._rect, dst._surf, &rdst );
            x += ch._xadv;
        }
        return x;
    }

    uint text_width( const token& str ) const
    {
        uint w=0;
        for( uint i=0; i<str.len(); ++i )
        {
            uchar k = str[i];

            if( k >= _chars.size() )
                continue;
            if( !_chars[k].is_set() )
                continue;

            const Char& ch = *_chars[k];
            w += ch._xadv;
        }
        return w;
    }


    opcd load( const token& file )
    {
//common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1
//char id=32   x=0     y=0     width=1     height=0     xoffset=0     yoffset=32    xadvance=8     page=0 
        
        bifstream bif;
        opcd e = bif.open(file);
        if(e)  return e;

        cachestream cst(&bif);
        txtstream txt(&cst);
        binstreambuf buf;

        e = read_hdr( file, txt );
        if(e)  return e;

        CharP chl;
        _chars.need_new(128);

        for( ; 0 == txt.read_line( &buf ); buf.reset() )
        {
            token tok = buf;

            if(!chl.is_set())
                chl = new Char;

            uchar k = chl->read(tok);
            if(!k)  continue;

            _chars[k] = chl;
        }

        return 0;
    }

private:
    opcd read_hdr( token path, binstream& bin )
    {
        binstreambuf buf;
        if( 0 != bin.read_line( &buf ) )
            return ersIO_ERROR;

        token tin = buf;

        tin.skip_notchar('=');
        if( tin.is_empty() )
            return ersMISMATCHED;

        _clheight = tin.touint_and_shift(1);

        tin.skip_notchar('=');
        _base = tin.touint_and_shift(1);

        uint sw,sh;
        tin.skip_notchar('=');
        sw = tin.touint_and_shift(1);
        tin.skip_notchar('=');
        sh = tin.touint_and_shift(1);

        uint n;
        tin.skip_notchar('=');
        n = tin.touint_and_shift(1);

        charstr dir = path.cut_left_back( '.', 1 );
        dir += "_";
        uint pl = dir.len();

        _images.need_new(n);
        _images_inv.need_new(n);
        for( uint i=0; i<n; ++i )
        {
            dir.trim_to_length(pl);
            dir.append_num( 10, i, 2, charstr::ALIGN_NUM_FILL_WITH_ZEROS );
            dir += ".tga";

            opcd e = _images[i].readTGA(dir.ptr());
            if(e)  return e;

            if( _images[i].width() != sw  ||  _images[i].height() != sh )
                return ersMISMATCHED;

            SDL_SetAlpha( _images[i]._surf, 0, 0 );
            _images[i].set_colorkey( true, 0, true );
            //SDL_SetColorKey( _images[i]._surf, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0 );

            _images[i].duplicate( _images_inv[i], true );
            _images_inv[i].invert();

            SDL_SetAlpha( _images_inv[i]._surf, 0, 0 );
            _images_inv[i].set_colorkey( true, 0x00ffffff, true );
        }

        return 0;
    }

protected:

    uint16  _clheight;
    uint16  _base;

    typedef local<Char>     CharP;
    
    dynarray<CharP>     _chars;
    dynarray<TexImage>  _images;
    dynarray<TexImage>  _images_inv;
};



#endif //__TEXIMAGE_FONT__HEADER_FILE__
